package com.hh.demo.mq.listener;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.hh.demo.domain.CourseOrder;
import com.hh.demo.dto.PayDto;
import com.hh.demo.service.ICourseOrderItemService;
import com.hh.demo.service.ICourseOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;

/**
 * 生产者的事务监听器，保证本地事务和发送消息的原子性，要么都成功，要么都失败
 * @author 黄浩
 * @create 2022-07-31 19:31
 */
@Component
@RocketMQTransactionListener(
        txProducerGroup = "order-producer"
)
@Slf4j
public class CourseOrderRocketMqListener implements RocketMQLocalTransactionListener {
    @Resource
    private ICourseOrderService courseOrderService;
    @Resource
    private ICourseOrderItemService courseOrderItemService;

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        log.info("开始执行本地事务");
        if (o==null){
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        try {
            CourseOrder courseOrder = (CourseOrder) o;
            //保存主订单和子订单
            courseOrderService.insert(courseOrder);
            courseOrder.getItems().forEach(item->{
                item.setOrderId(courseOrder.getId());
                courseOrderItemService.insert(item);
            });
        } catch (Exception e) {
            e.printStackTrace();
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        return RocketMQLocalTransactionState.COMMIT;
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        log.info("开始检查本地事务状态");
        try {
            byte[] payload = (byte[]) message.getPayload();
            String str = new String(payload, StandardCharsets.UTF_8);
            PayDto payDto = JSONObject.parseObject(str, PayDto.class);
            CourseOrder courseOrder = courseOrderService.selectOne(new EntityWrapper<CourseOrder>().eq("order_no", payDto.getOrderNo()));
            return courseOrder != null?RocketMQLocalTransactionState.COMMIT:RocketMQLocalTransactionState.ROLLBACK;
        } catch (Exception e) {
            e.printStackTrace();
            return RocketMQLocalTransactionState.ROLLBACK;
        }

    }
}
